// ============ AI工具调度系统 - 多轮工具调用编排器 ============

import type { 
  OrchestrationOptions, 
  OrchestrationResult, 
  ChatMessage,
  ToolCallResponse
} from './types';
import { validateToolCall, generateId } from './utils';

/**
 * 多轮工具调用编排器 - 支持递归工具调用直到收敛
 * @param chatResponse chat.complete 的返回结果（包含可能的 tool_calls）
 * @param modelKey 当前模型键
 * @param messages 当前消息历史
 * @param options 执行选项
 * @returns 工具调用执行结果
 */
export async function orchestrateToolCalls(
  chatResponse: { content: string; raw: any },
  modelKey: string,
  messages: Array<ChatMessage>,
  store: any, // AI工具存储实例
  options: OrchestrationOptions = {}
): Promise<OrchestrationResult> {
  const {
    maxRounds = 100,
    enableMultiRound = true,
    abortSignal,
    onRoundComplete,
    onMessageUpdate,
    onAssistantResponse,
    onToolCallStart
  } = options;

  let currentMessages = [...messages];
  let currentResponse = chatResponse;
  let totalRounds = 0;
  let hasAnyToolCalls = false;

  // 先显示初始 AI 响应（如果有内容）
  if (currentResponse.content && currentResponse.content.trim()) {
    onAssistantResponse?.(currentResponse.content);
  }

  // 递归执行多轮工具调用
  while (totalRounds < maxRounds) {
    // 检查中断信号
    if (abortSignal?.aborted) {
      console.log('[Orchestrator] Aborted by signal');
      break;
    }

    const raw = currentResponse.raw;
    let toolCalls = raw?.choices?.[0]?.message?.tool_calls;
    
    // 如果没有工具调用，结束循环
    if (!toolCalls || !Array.isArray(toolCalls) || toolCalls.length === 0) {
      console.log(`[Orchestrator] No tool calls in round ${totalRounds + 1}, ending`);
      break;
    }

    // 🔧 验证和过滤工具调用，移除无效的工具调用
    const { validToolCalls, invalidErrors } = filterAndValidateToolCalls(toolCalls);
    
    // 处理无效工具调用
    if (invalidErrors.length > 0) {
      handleInvalidToolCalls(currentMessages, invalidErrors);
    }

    // 如果所有工具调用都无效，继续下一轮
    if (validToolCalls.length === 0) {
      const shouldContinue = await handleAllInvalidToolCalls(
        currentMessages, 
        store, 
        modelKey, 
        totalRounds,
        abortSignal,
        onMessageUpdate,
        onAssistantResponse
      );
      
      if (!shouldContinue) break;
      
      // 获取下一轮响应
      try {
        currentResponse = await getNextRoundResponse(currentMessages, store, modelKey, abortSignal);
        if (currentResponse?.content && currentResponse.content.trim()) {
          onAssistantResponse?.(currentResponse.content);
        }
        continue;
      } catch (error) {
        console.error(`[Orchestrator] Error handling invalid tool calls:`, error);
        break;
      }
    }

    // 使用验证后的工具调用
    toolCalls = validToolCalls;
    hasAnyToolCalls = true;
    totalRounds++;

    console.log(`[Orchestrator] Round ${totalRounds}: Processing ${toolCalls.length} valid tool calls`);
    
    // 触发工具调用开始回调
    onToolCallStart?.(totalRounds, toolCalls);
    
    // 1. 追加 assistant 消息（只包含有效的 tool_calls）
    const assistantMsg = {
      role: 'assistant',
      content: currentResponse.content || '',
      tool_calls: toolCalls, // 使用过滤后的有效工具调用
      id: generateId('assistant'),
      rt: 0
    };
    currentMessages.push(assistantMsg);
    
    // 实时更新消息
    onMessageUpdate?.(currentMessages.slice());

    // 2. 执行当前轮次的工具调用
    const toolResults = await executeToolCallsRound(toolCalls, store, abortSignal);
    
    // 3. 追加工具结果消息
    for (const toolResult of toolResults) {
      const toolMsg = {
        role: 'tool',
        content: toolResult.content,
        id: generateId('tool'),
        rt: 0,
        ...(toolResult.tool_call_id ? { tool_call_id: toolResult.tool_call_id } : {}),
        ...(toolResult.name ? { name: toolResult.name } : {})
      };
      currentMessages.push(toolMsg);
    }
    
    // 实时更新消息
    onMessageUpdate?.(currentMessages.slice());

    // 触发轮次完成回调
    onRoundComplete?.(totalRounds, toolResults);

    // 如果不启用多轮，在第一轮后停止
    if (!enableMultiRound) {
      console.log('[Orchestrator] Multi-round disabled, stopping after first round');
      break;
    }

    console.log(`[Orchestrator] Round ${totalRounds} completed, continuing to next round`);

    // 4. 获取下一轮响应
    try {
      currentResponse = await getNextRoundResponse(currentMessages, store, modelKey, abortSignal);
      
      if (currentResponse?.content && currentResponse.content.trim()) {
        onAssistantResponse?.(currentResponse.content);
      }
    } catch (error) {
      console.error(`[Orchestrator] Error in round ${totalRounds}:`, error);
      break;
    }
  }

  console.log(`[Orchestrator] Completed ${totalRounds} rounds with tool calls`);
  
  // 如果有工具调用，获取最终的文本回答
  let finalResponse = '';
  if (hasAnyToolCalls) {
    try {
      finalResponse = await getFinalResponse(currentMessages, store, modelKey, abortSignal);
      if (finalResponse) {
        onAssistantResponse?.(finalResponse);
        // 添加最终回答到消息列表
        currentMessages.push({
          role: 'assistant',
          content: finalResponse,
          id: generateId('assistant-final'),
          rt: 0
        });
        // 最终更新消息
        onMessageUpdate?.(currentMessages.slice());
      }
    } catch (error) {
      console.error('[Orchestrator] Error getting final response:', error);
    }
  }

  return { 
    hasToolCalls: hasAnyToolCalls, 
    updatedMessages: hasAnyToolCalls ? currentMessages : undefined,
    totalRounds,
    finalResponse
  };
}

/**
 * 过滤和验证工具调用
 */
function filterAndValidateToolCalls(toolCalls: any[]): { 
  validToolCalls: any[]; 
  invalidErrors: any[] 
} {
  const validToolCalls = [];
  const invalidErrors = [];
  
  for (const toolCall of toolCalls) {
    if (validateToolCall(toolCall)) {
      validToolCalls.push(toolCall);
    } else {
      console.warn('[Orchestrator] Filtering out invalid tool call:', toolCall);
      
      invalidErrors.push({
        tool_call_id: toolCall?.id,
        role: 'tool' as const,
        name: 'invalid_tool',
        content: JSON.stringify({ 
          error: 'Invalid tool call: missing or empty function name',
          original_call: toolCall
        })
      });
    }
  }
  
  return { validToolCalls, invalidErrors };
}

/**
 * 处理无效工具调用
 */
function handleInvalidToolCalls(currentMessages: any[], invalidErrors: any[]): void {
  // 为无效工具调用添加一个特殊的 assistant 消息（不包含 tool_calls）
  currentMessages.push({
    role: 'assistant',
    content: `检测到 ${invalidErrors.length} 个无效的工具调用，正在处理错误...`,
    id: generateId('assistant-invalid'),
    rt: 0
  });
  
  // 添加错误响应消息
  for (const errorResult of invalidErrors) {
    currentMessages.push({
      role: 'tool',
      content: errorResult.content,
      id: generateId('tool-invalid'),
      rt: 0,
      tool_call_id: errorResult.tool_call_id,
      name: errorResult.name
    });
  }
}

/**
 * 处理所有工具调用都无效的情况
 */
async function handleAllInvalidToolCalls(
  currentMessages: any[],
  store: any,
  modelKey: string,
  totalRounds: number,
  abortSignal?: AbortSignal,
  onMessageUpdate?: (messages: any[]) => void,
  onAssistantResponse?: (response: string) => void
): Promise<boolean> {
  console.warn(`[Orchestrator] All tool calls in round ${totalRounds + 1} are invalid, continuing with error responses`);
  
  // 实时更新消息
  onMessageUpdate?.(currentMessages.slice());
  
  return true; // 继续处理
}

/**
 * 获取下一轮响应
 */
async function getNextRoundResponse(
  currentMessages: any[],
  store: any,
  modelKey: string,
  abortSignal?: AbortSignal
): Promise<any> {
  // 构建可用工具列表（排除 chat.complete）
  const registeredTools = store.registeredTools || [];
  const availableTools = registeredTools
    .filter((t: any) => t.id !== 'chat.complete')
    .map((t: any) => ({
      type: 'function',
      function: {
        name: t.id,
        description: t.description,
        parameters: t.parameters || undefined
      }
    }));

  // 调用模型获取下一轮响应
  const nextResult = await store.executeTool({
    toolId: 'chat.complete',
    parameters: { 
      messages: currentMessages, 
      modelKey, 
      tools: availableTools, 
      toolChoice: 'auto'
    },
    metadata: { signal: abortSignal }
  });

  if (!nextResult.success) {
    throw new Error(`Failed to get next round response: ${nextResult.error}`);
  }

  return nextResult.data;
}

/**
 * 获取最终响应
 */
async function getFinalResponse(
  currentMessages: any[],
  store: any,
  modelKey: string,
  abortSignal?: AbortSignal
): Promise<string> {
  console.log('[Orchestrator] Getting final response without tools');
  
  const finalResult = await store.executeTool({
    toolId: 'chat.complete',
    parameters: { 
      messages: currentMessages, 
      modelKey, 
      toolChoice: 'none' // 强制不使用工具
    },
    metadata: { signal: abortSignal }
  });
  
  if (finalResult.success) {
    return finalResult.data?.content || '';
  }
  
  throw new Error('Failed to get final response');
}

/**
 * 执行单轮工具调用
 */
export async function executeToolCallsRound(
  toolCalls: any[],
  store: any,
  abortSignal?: AbortSignal
): Promise<ToolCallResponse[]> {
  const results: ToolCallResponse[] = [];
  
  // 支持并发执行工具（可配置串行/并发）
  const ENABLE_CONCURRENT_TOOLS = true;
  
  if (ENABLE_CONCURRENT_TOOLS) {
    // 并发执行所有工具
    const promises = toolCalls.map(toolCall => executeToolCall(toolCall, store, abortSignal));
    const toolResults = await Promise.allSettled(promises);
    
    for (let i = 0; i < toolResults.length; i++) {
      const result = toolResults[i];
      if (result.status === 'fulfilled') {
        results.push(result.value);
      } else {
        // 处理失败的工具调用
        const toolCall = toolCalls[i];
        results.push({
          tool_call_id: toolCall?.id,
          role: 'tool' as const,
          name: toolCall?.function?.name,
          content: JSON.stringify({ error: result.reason?.message || 'Tool execution failed' })
        });
      }
    }
  } else {
    // 串行执行工具
    for (const toolCall of toolCalls) {
      if (abortSignal?.aborted) break;
      const result = await executeToolCall(toolCall, store, abortSignal);
      results.push(result);
    }
  }
  
  return results;
}

/**
 * 执行单个工具调用
 */
export async function executeToolCall(
  toolCall: any,
  store: any,
  abortSignal?: AbortSignal
): Promise<ToolCallResponse> {
  const callId = toolCall?.id;
  const func = toolCall?.function;
  
  // 🔧 增强验证：更严格的参数检查
  if (!validateToolCall(toolCall)) {
    console.warn('[Orchestrator] Invalid tool call - missing or invalid function name:', toolCall);
    return {
      tool_call_id: callId,
      role: 'tool',
      name: 'invalid_tool',
      content: JSON.stringify({ 
        error: 'Invalid tool call: function name is missing, null, or empty',
        received: func,
        call_id: callId
      })
    };
  }

  const toolId = func.name.trim();
  const toolDef = store.getTool(toolId);
  
  if (!toolDef) {
    console.warn(`[Orchestrator] Tool not found: ${toolId}`);
    return {
      tool_call_id: callId,
      role: 'tool',
      name: toolId,
      content: JSON.stringify({ 
        error: `Tool '${toolId}' is not registered`,
        available_tools: (store.registeredTools || []).map((t: any) => t.id),
        call_id: callId
      })
    };
  }

  // 🔧 增强参数解析：更好的错误处理
  let parameters: any = {};
  try {
    if (func.arguments) {
      if (typeof func.arguments === 'string') {
        parameters = JSON.parse(func.arguments);
      } else if (typeof func.arguments === 'object') {
        parameters = func.arguments;
      } else {
        throw new Error(`Invalid arguments type: ${typeof func.arguments}`);
      }
    }
  } catch (error) {
    console.error(`[Orchestrator] Failed to parse tool arguments for ${toolId}:`, error);
    return {
      tool_call_id: callId,
      role: 'tool',
      name: toolId,
      content: JSON.stringify({ 
        error: 'Failed to parse tool arguments: ' + String(error),
        raw_arguments: func.arguments,
        call_id: callId
      })
    };
  }

  // 🔧 执行工具：全面的错误捕获
  console.log(`[Orchestrator] Executing tool: ${toolId}`, parameters);
  try {
    const result = await store.executeTool({
      toolId,
      parameters,
      metadata: { 
        timeout: 30000, // 30秒超时
        signal: abortSignal
      }
    });

    // 🔧 处理工具执行结果
    if (!result) {
      return {
        tool_call_id: callId,
        role: 'tool',
        name: toolId,
        content: JSON.stringify({ 
          error: 'Tool execution returned null or undefined result',
          call_id: callId
        })
      };
    }

    let toolContent: string;
    try {
      if (result.success) {
        toolContent = JSON.stringify(result.data);
      } else {
        toolContent = JSON.stringify({ 
          error: result.error || 'Tool execution failed',
          error_type: result.errorType || 'unknown',
          call_id: callId
        });
      }
    } catch (serializationError) {
      console.error(`[Orchestrator] Failed to serialize tool result for ${toolId}:`, serializationError);
      toolContent = JSON.stringify({ 
        error: 'Failed to serialize tool result: ' + String(serializationError),
        call_id: callId
      });
    }

    return {
      tool_call_id: callId,
      role: 'tool',
      name: toolId,
      content: toolContent
    };
  } catch (error) {
    // 🔧 最高级别的错误捕获：确保任何异常都不会导致流程中断
    console.error(`[Orchestrator] Critical error in tool execution for ${toolId}:`, error);
    
    // 分类错误类型
    let errorType = 'unknown';
    let errorMessage = String(error);
    
    if (error && typeof error === 'object') {
      if ((error as any).name === 'AbortError' || /abort/i.test(errorMessage)) {
        errorType = 'aborted';
        errorMessage = 'Tool execution was aborted';
      } else if (/timeout/i.test(errorMessage)) {
        errorType = 'timeout';
        errorMessage = 'Tool execution timed out';
      } else if ((error as any).message) {
        errorMessage = (error as any).message;
      }
    }
    
    return {
      tool_call_id: callId,
      role: 'tool',
      name: toolId,
      content: JSON.stringify({ 
        error: errorMessage,
        error_type: errorType,
        tool_id: toolId,
        call_id: callId,
        timestamp: new Date().toISOString()
      })
    };
  }
}